package com.tanhua.server.service;

import cn.hutool.core.collection.CollUtil;
import com.alibaba.cloud.commons.lang.StringUtils;
import com.tanhua.autoconfig.template.AipFaceTemplate;
import com.tanhua.autoconfig.template.OssTemplate;
import com.tanhua.dubbo.api.*;
import com.tanhua.model.domain.User;
import com.tanhua.model.domain.UserInfo;
import com.tanhua.model.mongo.Friend;
import com.tanhua.model.mongo.UserLike;
import com.tanhua.model.mongo.Visitors;
import com.tanhua.model.vo.CountVo;
import com.tanhua.model.vo.ErrorResult;
import com.tanhua.model.vo.PageResult;
import com.tanhua.model.vo.UserInfoVo;
import com.tanhua.server.exception.BusinessException;
import com.tanhua.server.interceptor.UserHolder;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.jnlp.ClipboardService;
import java.io.IOException;
import java.time.Duration;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class UserInfoService {

    @DubboReference
    private UserInfoApi userInfoApi;

    @Autowired
    private OssTemplate ossTemplate;

    @Autowired
    private AipFaceTemplate aipFaceTemplate;

    @DubboReference
    private UserApi userApi;
    @Autowired
    private RedisTemplate<String,String> redisTemplate;

    @DubboReference
    private FriendApi friendApi;

    @DubboReference
    private UserLikeApi userLikeApi;

    @DubboReference
    private VisitorsApi visitorsApi;

    public void save(UserInfo userInfo) {
        userInfoApi.save(userInfo);
    }

    //更新用户头像
    public void updateHead(MultipartFile headPhoto, Long id) throws IOException {
        //1、将图片上传到阿里云oss
        String imageUrl = ossTemplate.upload(headPhoto.getOriginalFilename(), headPhoto.getInputStream());
        //2、调用百度云判断是否包含人脸
        boolean detect = aipFaceTemplate.detect(imageUrl);
        //2.1 如果不包含人脸，抛出异常
        if(!detect) {
            throw new BusinessException(ErrorResult.faceError());
        }else{
            //2.2 包含人脸，调用API更新
            UserInfo userInfo = new UserInfo();
            userInfo.setId(id);
            userInfo.setAvatar(imageUrl);
            userInfoApi.update(userInfo);
        }
    }

    //根据id查寻
    public UserInfoVo findById(Long id) {
        UserInfo userInfo = userInfoApi.findById(id);

        UserInfoVo vo = new UserInfoVo();

        BeanUtils.copyProperties(userInfo,vo); //copy同名同类型的属性

        if(userInfo.getAge() != null) {
            vo.setAge(userInfo.getAge().toString());
        }

        return vo;
    }

    //更新
    public void update(UserInfo userInfo) {
        userInfoApi.update(userInfo);
    }

    /**
     * 修改手机号，发送验证码
     *
     * @param
     */
    public void sendCode() {
        //1.获取用户的手机号和验证码
        String phone = UserHolder.getMobile();
        //根据手机号查询该用户是否存在
        User user = userApi.findByMobile(phone);


        String key = "CHECK_CODE_" + phone;
        //1.随机生成6位数验证码
//        String code = RandomStringUtils.randomNumeric(6);
        String code = "123456";
        //2.利用阿里云发送验证码
//        smsTemplate.sendSms(phone, code);
        //3.利用redis存储验证码
        redisTemplate.opsForValue().set(key, code, Duration.ofMinutes(5));
    }

    //验证手机验证码-修改手机
    public Map checkCode(Map map) {
        //1.获取用户的手机号和验证码
        String phone = UserHolder.getMobile();
        String code = (String) map.get("verificationCode");
        String key="CHECK_CODE_" + phone;
        //2.去除存在redis中的验证码比对
        String verificationCode = redisTemplate.opsForValue().get(key);
        //2.1如果验证码不合法，抛异常
        if (StringUtils.isEmpty(code) || !code.equals(verificationCode)) {
            throw new BusinessException(ErrorResult.loginError());

        }
        //2.2如果验证码合法，删除验证码
        redisTemplate.delete(key);
       /* //3.通过手机号查该手机是否已存在
        Boolean isNew=false;
        User user = userService.findByPhone(phone);
        //3.1如果是新用户，添加用户，打包返回
        if (user == null) {
            user = new User();
            user.setMobile(phone);
            user.setPassword(DigestUtils.md5Hex("123456"));
            Long userId=userService.save(user);
            user.setId(userId);
            isNew=true;
            //注册环信用户
            String username="hx"+user.getId();
            Boolean aBoolean = huanXinTemplate.createUser(username, "123456");
            if (aBoolean) {
                //设置环信账号和密码，添加进user表
                user.setHxUser(username);
                user.setHxPassword("123456");
                userService.save(user);
            }

        }


        //4.登陆成功，生成token
        Map<String,Object> tokenMap = new HashMap<>();
        tokenMap.put("id", user.getId());
        tokenMap.put("phone", phone);
        String token = JwtUtils.getToken(tokenMap);
        //5.封装数据返回
        Map<String, Object> resultMap = new HashMap<>();
        resultMap.put("token", token);
        resultMap.put("isNew", isNew);
        return resultMap;*/
        Map result = new HashMap();
        result.put("verification", true);
        return result;
    }

    /**
     * 保存手机号
     * @param map
     */
    public void updatePhone(Map map) {
        //获取要更新的手机号
        String phone = map.get("phone").toString();
        int length = phone.length();
        if (length != 11) {
            throw new BusinessException(ErrorResult.builder().errMessage("手机号长度不为11位").build());
        }
        //3.通过手机号查该手机是否已存在
        Boolean isNew=false;
        User user = userApi.findByMobile(phone);
        //3.1如果存在，抛异常
        if (user!=null) {
            throw new BusinessException(ErrorResult.mobileError());
        }
        //如果不存在，就修改当前用户手机号
        User user1 = userApi.findById(UserHolder.getUserId());
        user1.setMobile(phone);
        userApi.update(user1);
    }

    /**
     * 更新用户头像
     *
     * @param headPhoto
     */
    public void updateHeadPhoto(MultipartFile headPhoto) throws IOException {
        //1.图片上传到阿里云
        String imgUrl = ossTemplate.upload(headPhoto.getOriginalFilename(), headPhoto.getInputStream());
        //2.调用百度云查看是否包含人脸
        boolean detect = aipFaceTemplate.detect(imgUrl);
        //3.不包含人脸抛异常
        if (!detect) {
            throw new BusinessException(ErrorResult.faceError());
        }
        //4.包含人脸进行更新
        UserInfo userInfo = new UserInfo();
        userInfo.setId(UserHolder.getUserId());
        userInfo.setAvatar(imgUrl);
       // userInfoApi.updateHeadPhoto(userInfo);
    }



    //查询朋友(互相喜欢  type==1)
    public PageResult selectFriend(Integer page, Integer pagesize, String nickname) {
        Long userId = UserHolder.getUserId();
        List<Long> userIds = new ArrayList<>();
        if (nickname!=null){
            List<UserInfo> byname = userInfoApi.findByname(nickname);
            userIds = CollUtil.getFieldValues(byname,"id",Long.class);
        }
        List<Friend> friends = friendApi.findByUserId(userId, page, pagesize, userIds);
        if (friends.size()==0){
            throw new BusinessException(ErrorResult.friendError());
        }
        Long count = friendApi.getCount(userId);
        List<Long> friendId = CollUtil.getFieldValues(friends, "friendId", Long.class);
        Map<Long, UserInfo> map = userInfoApi.findByIds(friendId, null);
        PageResult pageResult = getPageResult(page, pagesize, count, friendId, map);
        return pageResult;
    }

    //抽取出的生成userinfovo的方法
    private PageResult getPageResult(Integer page, Integer pagesize, Long count, List<Long> friendId, Map<Long, UserInfo> map) {
        List<UserInfoVo> userInfos = new ArrayList<>();

        for (Long id : friendId) {
            UserInfoVo userInfoVo = new UserInfoVo();
            UserInfo userInfo = map.get(id);
            BeanUtils.copyProperties(userInfo,userInfoVo);
            userInfoVo.setAlreadyLove(true);
            userInfoVo.setMatchRate(86);
            userInfos.add(userInfoVo);
        }

        return new PageResult(page, pagesize, count, userInfos);
    }

    //我喜欢的人
    public PageResult selectIlike(Integer page, Integer pagesize, String nickname) {
        Long userId = UserHolder.getUserId();
        List<Long> userIds = new ArrayList<>();
        if (nickname!=null){
            List<UserInfo> byname = userInfoApi.findByname(nickname);
            userIds = CollUtil.getFieldValues(byname,"id",Long.class);
        }
        List<UserLike> userLikes = userLikeApi.getIlike(userId,page,pagesize,true,userIds);
        if (userLikes.size()==0){
            throw new BusinessException(ErrorResult.likeUserError());
        }
        List<Long> likeUserId = CollUtil.getFieldValues(userLikes, "likeUserId", Long.class);
        Map<Long, UserInfo> map = userInfoApi.findByIds(likeUserId, null);
        Long count = userLikeApi.getCount(userId,true,2);
        PageResult pageResult = getPageResult(page, pagesize, count, likeUserId, map);
        return pageResult;
    }

    //喜欢我的人  fans
    public PageResult selectlikeme(Integer page, Integer pagesize, String nickname) {
        Long userId = UserHolder.getUserId();
        List<Long> userIds = new ArrayList<>();
        if (nickname!=null){
            List<UserInfo> byname = userInfoApi.findByname(nickname);
            userIds = CollUtil.getFieldValues(byname,"id",Long.class);
        }
        //查询喜欢我的人的userlike
        List<UserLike> userLikes = userLikeApi.getLikeme(userId,page,pagesize,true,userIds);
        if (userLikes.size()==0){
            throw new BusinessException(ErrorResult.fansUserError());
        }
        //查出我的朋友
        Map<Long,Friend> friendMap = friendApi.getBymyid(userId);
        //提取出对象中的喜欢用户人的id
        List<Long> likemeId = CollUtil.getFieldValues(userLikes, "userId", Long.class);
        //根据id查询userinfo
        Map<Long, UserInfo> map = userInfoApi.findByIds(likemeId, null);
        //查询总数
        Long count = userLikeApi.getCount(userId, true, 3);
        //生成返回值
        List<UserInfoVo> userInfos = new ArrayList<>();

        for (Long id : likemeId) {

            UserInfoVo userInfoVo = new UserInfoVo();
            UserInfo userInfo = map.get(id);
            BeanUtils.copyProperties(userInfo,userInfoVo);
            Friend friend = friendMap.get(id);
            if (friend == null){
                userInfoVo.setAlreadyLove(false);
            }else {
                userInfoVo.setAlreadyLove(true);
            }
            userInfoVo.setMatchRate(86);
            userInfos.add(userInfoVo);
        }

        return new PageResult(page, pagesize, count, userInfos);

    }

    //查询看过我的人
    public PageResult selectSeeme(Integer page, Integer pagesize, String nickname) {
        Long userId = UserHolder.getUserId();

        List<Visitors> visitors = visitorsApi.queryMyVisitorspage(userId, null,page,pagesize);
        if (visitors.size()==0){
            throw new BusinessException(ErrorResult.error());
        }
        List<Long> visitorUserId = CollUtil.getFieldValues(visitors, "visitorUserId", Long.class);
        Map<Long, UserInfo> map = userInfoApi.findByIds(visitorUserId, null);
        Long count = visitorsApi.getCount(userId);
        PageResult pageResult = getPageResult(page, pagesize, count, visitorUserId, map);
        return pageResult;
    }

    //喜欢取消
    public void makeunlike(Long id) {
        Long userId = UserHolder.getUserId();

        //为朋友删除friends关系在删除userlike关系
        Boolean aBoolean = friendApi.delectByid(userId, id);
        //不为朋友，删除userlike数据
        userLikeApi.remove(userId,id);
    }

    //对粉丝进行喜欢
    public void likefans(Long id) {
        Long userId = UserHolder.getUserId();
        //在userlike表内添加喜欢fans数据
        Boolean aBoolean = userLikeApi.saveOrUpdate(userId, id, true);
        //在friend表内添加数据
        friendApi.save(userId,id);
    }


    //查询喜欢列表的总数
    public CountVo getCount() {
        Long userId = UserHolder.getUserId();

        Long eachLoveCount = friendApi.getCount(userId);
        Long loveCount = userLikeApi.getCount(userId,true,2);
        Long fanCount = userLikeApi.getCount(userId,true,3);
        CountVo countVo = new CountVo(eachLoveCount, loveCount, fanCount);
        return countVo;
    }
}
